package com.nidu.demo.mail.gatewayimpl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.cola.dto.PageResponse;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.nidu.demo.mail.convertor.MailAccountConvertor;
import com.nidu.demo.mail.gateway.MailAccountGateway;
import com.nidu.demo.mail.mapper.MailAccountMapper;
import com.nidu.demo.mail.mapper.dataobject.MailAccountDO;
import com.nidu.demo.mail.model.MailAccount;
import com.nidu.demo.mail.model.MailAccountCriteria;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

/**
 * 邮件账号网关实现
 *
 * @author auto
 */
@Component
@RequiredArgsConstructor
public class MailAccountGatewayImpl implements MailAccountGateway {

    private final MailAccountMapper mapper;
    private final MailAccountConvertor convertor;

    @Override
    public MailAccount create(MailAccount mailAccount) {
        MailAccountDO mailAccountDO = convertor.toDataObject(mailAccount);
        mapper.insert(mailAccountDO);
        return convertor.toDomainObject(mailAccountDO);
    }

    @Override
    public MailAccount update(MailAccount mailAccount) {
        MailAccountDO mailAccountDO = convertor.toDataObject(mailAccount);
        mapper.updateById(mailAccountDO);
        return convertor.toDomainObject(mailAccountDO);
    }

    @Override
    public void deleteById(Long id) {
        mapper.deleteById(id);
    }

    @Override
    public void deleteByIds(Set<Long> ids) {
        mapper.deleteByIds(ids);
    }

    @Override
    public MailAccount getById(Long id) {
        MailAccountDO mailAccountDO = mapper.selectById(id);
        if (mailAccountDO == null) {
            return null;
        }
        return convertor.toDomainObject(mailAccountDO);
    }

    @Override
    public List<MailAccount> getByIds(Set<Long> ids) {
        LambdaQueryWrapper<MailAccountDO> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(MailAccountDO::getId, ids);
        List<MailAccountDO> mailAccountDOS = mapper.selectList(wrapper);
        if (CollUtil.isEmpty(mailAccountDOS)) {
            return new ArrayList<>();
        }
        return convertor.toDomainObjects(mailAccountDOS);
    }

    @Override
    public MailAccount getByMail(String mail) {
        LambdaQueryWrapper<MailAccountDO> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(MailAccountDO::getMail, mail);
        MailAccountDO mailAccountDO = mapper.selectOne(wrapper);
        if (mailAccountDO == null) {
            return null;
        }
        return convertor.toDomainObject(mailAccountDO);
    }

    @Override
    public List<MailAccount> listByCondition(MailAccountCriteria criteria) {
        LambdaQueryWrapper<MailAccountDO> wrapper = buildQueryWrapper(criteria);
        List<MailAccountDO> mailAccountDOS = mapper.selectList(wrapper);
        if (CollUtil.isEmpty(mailAccountDOS)) {
            return new ArrayList<>();
        }
        return convertor.toDomainObjects(mailAccountDOS);
    }

    @Override
    public PageResponse<MailAccount> pageByCondition(MailAccountCriteria criteria) {
        LambdaQueryWrapper<MailAccountDO> wrapper = buildQueryWrapper(criteria);
        IPage<MailAccountDO> page = new Page<>(criteria.getPageIndex(), criteria.getPageSize());
        IPage<MailAccountDO> result = mapper.selectPage(page, wrapper);
        
        PageResponse<MailAccount> pageResponse = new PageResponse<>();
        pageResponse.setPageIndex((int) result.getCurrent());
        pageResponse.setPageSize((int) result.getSize());
        pageResponse.setTotalCount((int) result.getTotal());
        pageResponse.setData(convertor.toDomainObjects(result.getRecords()));
        return pageResponse;
    }

    @Override
    public List<MailAccount> listAll() {
        List<MailAccountDO> mailAccountDOS = mapper.selectList(null);
        if (CollUtil.isEmpty(mailAccountDOS)) {
            return new ArrayList<>();
        }
        return convertor.toDomainObjects(mailAccountDOS);
    }

    private LambdaQueryWrapper<MailAccountDO> buildQueryWrapper(MailAccountCriteria criteria) {
        LambdaQueryWrapper<MailAccountDO> wrapper = new LambdaQueryWrapper<>();
        wrapper.like(!StrUtil.isEmpty(criteria.getMail()), MailAccountDO::getMail, criteria.getMail());
        wrapper.like(!StrUtil.isEmpty(criteria.getUsername()), MailAccountDO::getUsername, criteria.getUsername());
        wrapper.like(!StrUtil.isEmpty(criteria.getHost()), MailAccountDO::getHost, criteria.getHost());
        return wrapper;
    }

}
